/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package expression.interval;

/**
 *
 * @author ddoose
 */
public class IntBounded extends Interval {
    private int leftBound;
    private int rightBound;
    
    IntBounded(int l, int r) {
        leftBound = l;
        rightBound = r;
    }
    
    public int getLeftBound() {
        return leftBound;
    }
    
    public int getRightBound() {
        return rightBound;
    }
    
    public int getValue() {
        throw new UnsupportedOperationException("IntBounded has no value");
    }
    
    public boolean isEmpty() {
        return false;
    }

    public boolean isUniverse() {
        return false;
    }

    public boolean isLeftBounded() {
        return true;
    }

    public boolean isRightBounded() {
        return true;
    }
    
    public boolean isValue() {
        return false;
    }

    public Interval inter(Interval i) {
        if (this.isDisjoined(i)) {
            return new IntEmpty();
        }
        else if (i.isLeftBounded() && i.isRightBounded()) {
            int l = Math.max(leftBound, i.getLeftBound());
            int r = Math.min(rightBound, i.getRightBound());
            if (l == r) {
                return new IntValue(l);
            }
            else {
                return new IntBounded(l, r);
            }
        }
        else if (i.isLeftBounded()) {
            int l = Math.max(leftBound, i.getLeftBound());
            if (l == rightBound) {
                return new IntValue(l);
            }
            else {
                return new IntBounded(l, rightBound);
            }
        }
        else if (i.isRightBounded()) {
            int r = Math.min(rightBound, i.getRightBound());
            if (r == leftBound) {
                return new IntValue(r);
            }
            else {
                return new IntBounded(leftBound, r);
            }
        }
        else {
            return clone();
        }
    }
    
    public Interval union(Interval i) {
        if (i.isEmpty()) {
            return null;
        }
        else if (i.isLeftBounded() && i.isRightBounded()) {
            if (((i.getRightBound() >= leftBound -1) && (i.getRightBound() <= rightBound +1)) ||
                    ((i.getLeftBound() >= leftBound -1) && (i.getLeftBound() <= rightBound +1))) {
                int l = Math.min(leftBound, i.getLeftBound());
                int r = Math.max(rightBound, i.getRightBound());
                if (l == r) {
                    return new IntValue(l);
                }
                else {
                    return new IntBounded(l, r);
                }
            }
            else {
                return null;
            }
        }
        else {
            return i.union(this);
        }
    }
    
    public boolean equals(Interval i) {
        return (i instanceof IntBounded) && (leftBound == i.getLeftBound()) && (rightBound == i.getRightBound());
    }

    public Interval clone() {
        return new IntBounded(leftBound, rightBound);
    }

    public String toString() {
        return "[" + leftBound + " ; " + rightBound + "]";
    }
}
